package com.smartum.mpr.client.controller;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.RootPanel;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartum.mpr.client.event.LoginEvent;
import com.smartum.mpr.client.event.LoginEventHandler;
import com.smartum.mpr.client.event.TabClickHandler;
import com.smartum.mpr.client.presenter.*;
import com.smartum.mpr.client.utils.HistoryHelper;
import com.smartum.mpr.client.view.*;

/**
 * Front controller class is responsible for history navigation (implemented {@link ValueChangeHandler}, which monitor
 * {@link History} change).
 * <p/>
 * Also class initialize presenters and its views for the corresponding view. In addition it registers events for the
 * eventBus.
 */
public class MPRController implements ValueChangeHandler<String>, Presenter {

    private static final String HEADER_DIV_ID = "header";

    private HasWidgets container;
    private final HandlerManager eventBus;

    public MPRController() {
        this.eventBus = new HandlerManager(null);
    }

    /**
     * Adds handlers to the History and {@link HandlerManager eventBus}.
     */
    public void bind() {
        History.addValueChangeHandler(this);

        this.eventBus.addHandler(LoginEvent.TYPE, new LoginEventHandler());
    }

    public HandlerManager eventBus() {
        return this.eventBus;
    }

    /**
     * Calls when History change event fires.
     * <p/>
     * Login screen adds to the div with <code>content</code> id, and main layout will be separated into two different
     * areas: header and content. Header & content will be separate widgets.
     * <p/>
     * Before each navigation each container should be cleanuped.
     *
     * @param event event which fires on Window resize
     */
    public void onValueChange(ValueChangeEvent<String> event) {
        final String historyToken = event.getValue();

        final ContentViewerView contentViewerView = new ContentViewerView();
        final ContentViewerPresenter contentViewerPresenter = new ContentViewerPresenter(contentViewerView,
                this.eventBus());
        contentViewerView.getTabSet().addClickHandler(new TabClickHandler(contentViewerView.getTabSet()));

        if (HistoryHelper.LOGIN_TOKEN.equals(historyToken)) {
            RootPanel.get(HEADER_DIV_ID).clear();
            this.container.clear();

            final LoginView loginView = new LoginView();
            final LoginPresenter loginPresenter = new LoginPresenter(loginView, this.eventBus);

            loginPresenter.go(this.container);
            loginPresenter.bind();
        } else if (HistoryHelper.ADMIN_TOKEN.equals(historyToken)) {

            this.container.clear();

            contentViewerPresenter.go(this.container);
            contentViewerPresenter.bind();

            initializeHeader();
        } else if (HistoryHelper.NEWS_TOKEN.equals(historyToken)) {

            this.container.clear();

            contentViewerPresenter.go(this.container);
            contentViewerPresenter.bind();

            final Canvas newsPane = contentViewerView.getNewsTab().getPane();
            if (newsPane == null) {
                final NewsViewer newsViewer = new NewsViewer();
                final NewsViewerPresenter newsViewerPresenter = new NewsViewerPresenter(newsViewer, this.eventBus());
                newsViewerPresenter.go(contentViewerView.getNewsTab());
                newsViewerPresenter.bind();
            }

            contentViewerView.getTabSet().selectTab(1);

            initializeHeader();
        } else if (HistoryHelper.ITEMS_TOKEN.equals(historyToken)) {

            contentViewerPresenter.go(this.container);
            contentViewerPresenter.bind();

            final Canvas itemsPane = contentViewerView.getItemsTab().getPane();
            if (itemsPane == null) {
                final ItemsViewerPresenter itemsViewerPresenter = new ItemsViewerPresenter(new ItemsViewer(), this.eventBus());
                itemsViewerPresenter.go(contentViewerView.getItemsTab());
                itemsViewerPresenter.bind();
            }
            contentViewerView.getTabSet().selectTab(2);

            initializeHeader();
        } else if (HistoryHelper.JOBS_TOKEN.equals(historyToken)) {

            contentViewerPresenter.go(this.container);
            contentViewerPresenter.bind();

            final Canvas jobsPane = contentViewerView.getJobsTab().getPane();
            if (jobsPane == null) {
                final JobsViewerPresenter itemsViewerPresenter = new JobsViewerPresenter(new JobsViewer(),
                        this.eventBus());
                itemsViewerPresenter.go(contentViewerView.getJobsTab());
                itemsViewerPresenter.bind();
            }
            contentViewerView.getTabSet().selectTab(3);

            initializeHeader();
        }
    }

    private void initializeHeader() {
        final HeaderView headerView = new HeaderView();
        final HeaderPresenter headerPresenter = new HeaderPresenter(headerView, this.eventBus());

        headerPresenter.go(RootPanel.get(HEADER_DIV_ID));
        headerPresenter.bind();
    }

    public void go(HasWidgets container) {

        this.container = container;

        if (History.getToken() != null && !History.getToken().isEmpty()) {
            History.fireCurrentHistoryState();
        } else {
            HistoryHelper.navigateToken(HistoryHelper.LOGIN_TOKEN);
        }
    }
}
